// Biblotecas estandar
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
// Bibliotecas IPC
#include <sys/types.h>
#include <unistd.h>
// Clases que encapsulan los IPCs
#include "./IPC/Semaphore/Semaphore.h"
#include "./IPC/SharedMemory/ControlDataSharedMemory.h"
#include "./IPC/MessageQueue/TruckInputMessageQueue.h"
#include "./IPC/MessageQueue/TruckOutputMessageQueue.h"
#include "./IPC/MessageQueue/ChargeToTruckMessageQueue.h"


/* Definición de variables estáticas para pasar argumentos a los procesos */
static char param1[16];
static int i;
static char buffer[255];

/* Declaración de Funciones */
void init_IPCs(void);
void crearCamiones();



int main(int argc, char* argv[])
{		
	// Inicializo el entorno
	srand(getpid());
	init_IPCs();

	crearCamiones();
	return 0;
}

void init_IPCs() {

	ControlData data;
	
	// Colas utilizadas para la comunicación entre el Camión y las Personas 
	// al momento de subir
	TruckInputMessageQueue truckChargeInputQueueInput = TruckInputMessageQueue();
	truckChargeInputQueueInput.create((char *) DIRECTORY, ID_Q_TRUCK_CHARGE_INPUT);
	TruckOutputMessageQueue truckChargeOutputQueue = TruckOutputMessageQueue();
	truckChargeOutputQueue.create((char *) DIRECTORY, ID_Q_TRUCK_CHARGE_OUTPUT);
	
	// Colas utilizadas para la comunicación entre el Camión y las Personas 
	// al momento de subir
	TruckInputMessageQueue truckDischargeInputQueueInput = TruckInputMessageQueue();
	truckDischargeInputQueueInput.create((char *) DIRECTORY, ID_Q_TRUCK_DISCHARGE_INPUT);
	TruckOutputMessageQueue truckDischargeOutputQueue = TruckOutputMessageQueue();
	truckDischargeOutputQueue.create((char *) DIRECTORY, ID_Q_TRUCK_DISCHARGE_OUTPUT);
	
	// Cola en la cual el camión va recibiendo 
	ChargeToTruckMessageQueue chargeToTruckQueue = ChargeToTruckMessageQueue();
	chargeToTruckQueue.create((char *) DIRECTORY, ID_Q_CHARGE_TO_TRUCK);
	

	Semaphore semControl = Semaphore();	
	if (semControl.createSemaphore((char *) DIRECTORY, ID_SEMCONTROL, 1) != -1) {
		semControl.initializeSemaphore(0, 1);
	}
	
	Semaphore semTruck = Semaphore();
	semTruck.createSemaphore((char *) DIRECTORY, ID_SEMTRUCK, CANT_TRUCKS);
	for (int i = 0; i < CANT_TRUCKS; i++) {
		semTruck.initializeSemaphore(i, 0);
	}
	

	ControlDataSharedMemory shMem = ControlDataSharedMemory();
	if (shMem.createSharedMemory((char *) DIRECTORY, ID_SHMEM) != -1) {
		shMem.write(&data);
		shMem.read(&data);
		//sprintf(buffer, "Proceso LauncherPuertasCamiones - Valor inicial de cantPersonas: %d\n", 
		//data.cantPersonas);
		write(fileno(stdout), buffer, strlen(buffer));
	}

}

void crearCamiones() {
	pid_t pid;

	// Creo las 4 puertas de entrada
	for(i = 1; i <= CANT_TRUCKS; i++) {
		if ((pid = fork()) < 0) {
			sprintf(buffer, "Launcher Error: %s\n", strerror(errno));
			write(fileno(stdout), buffer, strlen(buffer));
		}				
		else if (pid == 0) {
			// Paso como parámetro a Puerta el número que identifica a 
			// la misma en el Museo (es un autoincrementable)
			sprintf(param1, "%d", i);
			execlp("./camion", "camion", param1, (char *) 0);
			sprintf(buffer, "Launcher Error: %s\n", strerror(errno));
			write(fileno(stdout), buffer, strlen(buffer));
		}
	}
}
